#include "Commn.hpp"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <errno.h>
#include <functional>
#include "Log.hpp"
#include "Protocol.hpp"


using namespace LogModule;

int main(int argc,char* argv[])
{
    ENABLE_CONSOLE_LOG_STRATEGY();
    if (argc != 3)
    {
        std::cout << "Usage Fail: use ./client_tcp server_ip server_port" << std::endl;
        return 1;
    }
    std::string ip = argv[1];
    uint16_t port = std::stoi(argv[2]);

    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd < 0)
    {
        LOG(LogLevel::DEBUG) << "socket create error";
        Die(SOCKET_ERROR);
    }
    //客户端不需要显示绑定， 但是由于tcp是面向字节流的，所以需要connect
    // int connect(int sockfd, const struct sockaddr *addr,
    //                socklen_t addrlen);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = ::htons(port);
    server_addr.sin_addr.s_addr = ::inet_addr(ip.c_str());
    socklen_t len = sizeof(server_addr);
    int n = connect(sockfd,CONV(&server_addr),len);
    if (n < 0)
    {
        LOG(LogLevel::DEBUG) << "connect error" << strerror(errno);
    }
    //此时就可以接受数据了

    std::string message;
    while(true)
    {
        // char inbuffer[1024];
        int x,y;
        char oper;
        std::cout << "input x: ";
        std::cin >> x;
        std::cout << "input oper: ";
        std::cin >> oper;
        std::cout << "input y: ";
        std::cin >> y;
        Request req(x,y,oper);
        std::string message;
        req.serialization(&message);
        Encode(message);
        // std::getline(std::cin,message);
        int n = ::send(sockfd,message.c_str(),message.size(),0);
        if (n > 0)
        {
            char inbuffer[1024];
            int ret = ::recv(sockfd,inbuffer,sizeof(inbuffer)-1,0);
            inbuffer[ret] = 0;
            //Decode
            std::string retstr = inbuffer;
            std::string result;
            Decode(retstr,&result);
            //输出结果
            std::cout << result << std::endl;
            //反序列化
            Response res;
            res.deserialization(result);
            //输出结果
            res.Print();
        }
        else if (n == 0) 
        {
            break;
        }
        else 
            return 1;
    }


    return 0;
}
